﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Kooboo.HtmlFunc.Function;
using Kooboo.HtmlFunc.Providers;

namespace Kooboo.HtmlFunc.Analysis.Visitors
{
    public class DetailVisitor : StartEndVisitor
    {
        public DetailVisitor(VisitorContext context)
            : base(context, FuncType.Detail)
        {
        }

        private IFuncTester _startCommentTester;
        protected override IFuncTester StartCommentTester
        {
            get
            {
                if (_startCommentTester == null)
                    _startCommentTester = new Testers.ParametricTester(this.Func.StartComment);
                return _startCommentTester;
            }
        }

        protected override object OnQualified(HtmlCommentNode startNode, HtmlCommentNode endNode)
        {
            var tester = (Testers.ParametricTester)this.StartCommentTester;
            var folderName = tester.GetParameter("folder");
            if (string.IsNullOrEmpty(folderName))
            {
                if (!this.Context.ThrowException)
                    return null;
                throw new Exceptions.ParameterEmptyException(this.Context.FileName, startNode, "folder");
            }

            // owner layout position
            int? order = null;
            IPosition ownerPosition = null;
            if (this.Context.Items.ContainsKey(FuncType.Position))
            {
                ownerPosition = (IPosition)this.Context.Items[FuncType.Position];
                order = ownerPosition.ChildCount++;
            }

            // add
            var detail = Provider.Factory.GetProvider<IDetail>();
            detail.ViewName = this.GetDetailViewName(tester.GetParameter("viewName"), folderName);
            detail.FolderName = folderName;
            detail.StartNode = startNode;
            detail.EndNode = endNode;
            detail.Order = order;
            detail.OwnerPosition = ownerPosition;
            this.Context.Result.Details.Add(detail);

            // ret context mark
            return detail;
        }

        private string GetDetailViewName(string viewName, string folderName)
        {
            if (!string.IsNullOrEmpty(viewName))
                return viewName;

            var count = this.Context.Result.Details.Count(o => o.FolderName.IgnoreCaseEquals(folderName));
            var subfix = (count == 0) ? string.Empty : count.ToString();
            return folderName + "_detail" + subfix;
        }

        protected override FuncType ExclusiveType
        {
            get
            {
                return this.FuncType
                    | FuncType.Menu
                    | FuncType.Label
                    | FuncType.HtmlBlockPart
                    | FuncType.HtmlPart
                    | FuncType.ViewPart
                    | FuncType.List;
            }
        }
    }
}
